<template>
  <div class="menu-management">
    <el-card style="height: 85vh;">
      <vxe-grid
        v-bind="gridOptions"
        ref="gridRef"
        @page-change="handlePageChange"
        v-on="gridEvents"
      >
        <template #operate="{ row }">
          <vxe-button
            v-for="btn in inTableButtons"
            :key="btn.code"
            size="small"
            :status="btn.status"
            mode="text"
            :icon="getButtonIcon(btn.code)"
            @click="
              handleRowAction(btn.code, row, {
                openEditPopup: handleEdit,
                handleSetting: handleSetting,
                removeRow: handleDelete,
              })
            "
            :content="btn.name"
          ></vxe-button>
        </template>
      </vxe-grid>
      <vxe-modal v-model="settingMenuPopup" title="设置菜单" show-footer>
        <template #default>
          <vxe-tree
            v-bind="treeOptions"
            height="500"
            v-model:check-node-keys="checkNodeKeys"
          ></vxe-tree>
        </template>
        <template #footer>
          <vxe-button
            @click="settingMenuPopup = false"
            content="取消"
          ></vxe-button>
          <vxe-button
            status="primary"
            @click="saveSelectedIds"
            content="保存"
          ></vxe-button>
        </template>
      </vxe-modal>
      <vxe-modal
        v-model="showEditPopup"
        :title="form.id ? '编辑' : '新建'"
        width="50%"
        show-footer
      >
        <template #default>
          <vxe-form
            :data="form"
            :items="popupFormItems"
            :rules="formRules"
            ref="formRef"
            title-align="right"
            title-width="100"
          >
          </vxe-form>
        </template>
        <template #footer>
          <vxe-button
            @click="showEditPopup = false"
            content="取消"
          ></vxe-button>
          <vxe-button
            status="primary"
            @click="confirmEvent"
            content="保存"
          ></vxe-button>
        </template>
      </vxe-modal>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, reactive } from "vue";
import { useRoute } from "vue-router";
import {
  initFieldData,
  getQueryMapPage,
  getQueryRowPage,
  getMenuTree,
  saveRoleMenu,
  sysDict,
  getRowById,
  saveEntity,
  delEntityById,
  queryTreeList,
} from "@/api";
import type {
  VxeGridProps,
  VxeGridListeners,
  VxeGridInstance,
  VxeColumnPropTypes,
} from "vxe-table";
import {
  VxeUI,
  type VxeFormInstance,
  type VxeFormPropTypes,
  type VxeTreeProps,
} from "vxe-pc-ui";
import { splitButtonsByLocation, permToButtons } from "@/utils/permission";
import {
  useTableActions,
  useRemoveRow,
  setupToolbar,
} from "@/utils/useTableActions";

interface RowVO {
  id: number;
  parentId: number | null;
  name: string;
  size: number;
  date: string;
}

// ==================== Refs ====================
const route = useRoute();
const gridRef = ref<VxeGridInstance<RowVO>>();
const loading = ref(false);
const total = ref(0);
const pageSize = ref(10);
const firstSegment = ref("");
const lastSegment = ref("");
const vuePermission = ref<any[]>([]);
const inTableButtons = ref<any[]>([]);
const formRef = ref<VxeFormInstance<RowVO>>();
const fieldList = ref<any[]>([]); // 定义组件级响应式变量
const form = ref<Record<string, any>>({}); // 表单数据
const showEditPopup = ref(false);
const popupFormItems = ref<any[]>([]); // 动态表单字段配置
const settingMenuPopup = ref(false);
// ==================== 动态字典选项（示例）====================
// 字典缓存：避免多次打开弹窗时重复请求
const dictCache = new Map();

async function getOptions(dictType: string) {
  if (dictCache.has(dictType)) {
    return dictCache.get(dictType);
  }

  try {
    const dict = await sysDict({
      field: "type",
      value: dictType, // ✅ 用传入的 dictType，而不是写死 "permission_type"
    });

    const options =
      dict.childList?.map((item: { value: any; label: any }) => ({
        value: String(item.value),
        label: item.label,
      })) || [];

    dictCache.set(dictType, options);
    return options;
  } catch (error) {
    console.error(`加载字典 ${dictType} 失败`, error);
    dictCache.set(dictType, []);
    return [];
  }
}
// ==================== Switch 渲染器 ====================
const flagCellRender = reactive<VxeColumnPropTypes.CellRender>({
  name: "VxeSwitch",
  props: {
    disabled: false,
  },
});

// ==================== vxe-grid 配置 ====================
const gridOptions = reactive<VxeGridProps<RowVO>>({
  border: true,
  size: "mini",

  showOverflow: true,
  columnConfig: {
    resizable: true,
  },
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  // height: 700,
  rowConfig: {
    isCurrent: true,
    isHover: true,
  },
  checkboxConfig: {
    highlight: true,
  },

  toolbarConfig: {
    buttons: [],
  },
  formConfig: {
    data: {},
    items: [],
  },
  pagerConfig: {
    pageSize: 10,
    pageSizes: [10, 20, 50, 100],
    layouts: [
      "Sizes",
      "PrevJump",
      "PrevPage",
      "Number",
      "NextPage",
      "NextJump",
      "FullJump",
      "Total",
    ],
  },
  columns: [],
});

// ==================== 事件监听 ====================
const gridEvents: VxeGridListeners = {
  formSubmit({ data }) {
    handleSearch(data);
  },
  formReset({ data }) {
    console.log("表单已重置");
  },
  toolbarButtonClick(params) {
    console.log(params.code);
    if (params.code == "add") {
      handleCreate();
    }
  },
};

// ==================== 操作方法 ====================
const { getButtonIcon, handleRowAction } = useTableActions<RowVO>({
  customAction(row) {
    console.log("自定义操作:", row.name);
  },
});
// 新增操作
const handleCreate = () => {
  openPopup(); // 无参数表示新增
};
const handleSetting = (id: string) => {
  settingMenuPopup.value = true;
  getMenuTreeData(id);
  roleId.value = id;
};

// 编辑操作
const handleEdit = (row: RowVO) => {
  openPopup(row); // 传入 row 数据
};

const handleDelete = (row: RowVO) => {
  removeRow(String(row.id));
};
const removeRow = (id: string) => {
  VxeUI.modal.confirm({
    title: "提示",
    content: "确定删除数据吗？",
    mask: false,
    lockView: false,
    onConfirm: async () => {
      const res = await delEntityById(lastSegment.value, { ids: id });
      if (res.code == 0) {
        ElMessage.success("删除成功");
        initData();
      } else {
        ElMessage.error(res.message);
      }
    },
  });
};

// 保存
const confirmEvent = async () => {
  try {
    const node = await saveEntity(lastSegment.value, form.value);
    if (node.code == 0) {
      ElMessage.success(form.value.id ? "编辑成功" : "新增成功");
      initData();
    } else {
      ElMessage.error(node.message);
    }
    // 关闭弹窗
    showEditPopup.value = false;
  } catch (error) {
    ElMessage.error(form.value.id ? "编辑失败" : "新增失败");
  }
};

// ==================== 搜索与分页 ====================
const handleSearch = (formData: any) => {
  const pager = gridOptions.pagerConfig;
  const params = {
    pageNumber: pager?.currentPage || 1,
    pageSize: pager?.pageSize || 10,
    ...formData,
  };
  getDataTable(firstSegment.value, lastSegment.value, params);
};

const handlePageChange = ({ currentPage, pageSize: newPageSize }) => {
  const formData = gridOptions.formConfig?.data || {};
  const params = {
    pageNumber: currentPage,
    pageSize: newPageSize,
    ...formData,
  };
  getDataTable(firstSegment.value, lastSegment.value, params);
};

// ==================== 数据加载 ====================
const formRules = reactive<VxeFormPropTypes.Rules<RowVO>>({});

// 动态更新 formRules
function updateFormRules() {
  // 清空旧规则
  Object.keys(formRules).forEach((key) => {
    delete formRules[key];
  });

  // 重新生成规则
  const formFields = fieldList.value.filter((field) => field.isForm === "1");

  formFields.forEach((field) => {
    const rules: VxeFormPropTypes.Rule[] = [];

    // 如果是必填项，添加 required 规则
    if (field.formRequire === "1") {
      const isInputLike = ["input", "textarea", "num_input"].includes(
        field.formType
      );
      rules.push({
        required: true,
        message: isInputLike ? `请输入${field.title}` : `请选择${field.title}`,
        trigger: "blur", // input 类 blur，select 类 change
      });
    }

    // ✅ 特殊字段：比如 age，可以加额外规则（示例：年龄 18-35）
    if (field.field === "age") {
      rules.push({
        validator({ itemValue }) {
          const val = Number(itemValue);
          if (isNaN(val)) return new Error("请输入有效数字");
          if (val < 18 || val > 35) {
            return new Error("年龄在 18 ~ 35 之间");
          }
        },
        trigger: "change",
      });
    }

    // 绑定规则到 formRules
    if (rules.length > 0) {
      formRules[field.field] = rules;
    }
  });
}
const getDataTable = async (first: string, last: string, params: any) => {
  loading.value = true;
  try {
    const result = last ? last.charAt(0).toUpperCase() + last.slice(1) : "";
    const res = await initFieldData({ className: result });
    if (!res || !res.childList) {
      console.error("接口数据格式错误", res);
      return;
    }
    if (!res || !res.childList) {
      console.error("接口数据格式错误", res);
      return;
    }

    // 将接口返回的字段列表赋值给响应式变量
    fieldList.value = Array.isArray(res.childList) ? res.childList : [];

    // 1. 处理搜索字段
    const searchFields = fieldList.value.filter((i) => i.isSearch === "1");

    const formItems: any[] = searchFields.map((field) => {
      const item: any = {
        field: field.field,
        title: field.title,
        dateFormat: field.dateFormat,
        itemRender: {},
      };

      if (field.formType === "input") {
        item.itemRender = {
          name: "VxeInput",
          attrs: { placeholder: `请输入${field.title}` },
        };
      } else if (field.formType === "select") {
        item.itemRender = {
          name: "VxeSelect",
          props: { placeholder: `请选择${field.title}` },
        };
      } else if (field.formType === "date") {
        item.itemRender = {
          name: "VxeDatePicker",
          props: { type: field.dateFormat, placeholder: `选择${field.title}` },
        };
      } else if (field.formType === "datetime") {
        item.itemRender = {
          name: "VxeDatePicker",
          props: {
            type: field.dateFormat,
            startPlaceholder: "开始时间",
            endPlaceholder: "结束时间",
          },
        };
      } else if (field.formType === "num_input") {
        item.itemRender = {
          name: "VxeNumberInput",
          props: { placeholder: `请输入${field.title}` },
        };
      } else if (field.formType === "textarea") {
        item.itemRender = {
          name: "VxeTextarea",
          props: {
            placeholder: `请输入${field.title}`,
            autosize: { minRows: 2, maxRows: 4 },
          },
        };
      }
      return item;
    });
    // 动态生成表单配置

   const updatedFields = [];

  for (const field of fieldList.value) {
    if (field.field === "customDeptNames") {
      // 调用 API 获取选项列表
      const option = await queryTreeList("dept", {});
      console.log(option);
      field.formType = 'select'
      field.isForm = '1'
      // 构建新的字段配置
      const newItem = {
        ...field,
        title: "权限部门",
        dateFormat: '',
        formRequire: '0',
        span: 12,
        itemRender: {
          name: "VxeSelect",
          option: option,
          props: { placeholder: `请选择${field.title}` },
          events: {
            change: (value, options) => {
              console.log(value, options);
            },
          },
        },
      };
      updatedFields.push(newItem);
    } else {
      // 对于不需要更改的字段，直接添加到新数组中
      updatedFields.push(field);
    }
  }
    console.log(updatedFields)
    const formFields = updatedFields.filter((field) => field.isForm === "1");

    const formItemsForPopup = formFields.map((field) => {
      const item: any = {
        field: field.field,
        title: field.title,
        dateFormat: field.dateFormat,
        formRequire: field.formRequire,
        span: 12,
        itemRender: {},
      };
      if (field.formType === "input") {
        item.itemRender = {
          name: "VxeInput",
          props: { placeholder: `请输入${field.title}` },
        };
      } else if (field.formType === "select") {
        item.itemRender = {
          name: "VxeSelect",
          props: { placeholder: `请选择${field.title}` },
          events: {
            change: (value, options) => {
              console.log(value, options);
            },
          },
        };
      } else if (field.formType === "date") {
        item.itemRender = {
          name: "VxeDatePicker",
          props: { type: field.dateFormat, placeholder: `选择${field.title}` },
        };
      } else if (field.formType === "datetime") {
        item.itemRender = {
          name: "VxeDatePicker",
          props: {
            type: field.dateFormat,
            startPlaceholder: "开始时间",
            endPlaceholder: "结束时间",
          },
        };
      } else if (field.formType === "radio") {
        item.itemRender = {
          name: "VxeRadioGroup",
          options: getOptions(field.dictType),
        };
      } else if (field.formType === "num_input") {
        item.itemRender = {
          name: "VxeNumberInput",
          props: { placeholder: `请输入${field.title}` },
        };
      } else if (field.formType === "textarea") {
        item.itemRender = {
          name: "VxeTextarea",
          props: { placeholder: `请输入${field.title}` },
        };
      }

      return item;
    });
    popupFormItems.value = formItemsForPopup;
    updateFormRules();
    // 添加查询按钮组
    formItems.push({
      itemRender: {
        name: "VxeButtonGroup",
        options: [
          { type: "submit", content: "搜索", status: "primary" },
          { type: "reset", content: "重置" },
        ],
      },
    });
    // 更新 formConfig
    gridOptions.formConfig = {
      data: {}, // 自动绑定
      items: formItems,
    };

    // 2. 处理表格列
    const tableColumns = fieldList.value
      .filter((item: any) => item.isTable === "1")
      .sort((a: any, b: any) => a.sort - b.sort)
      .map((item: any) => {
        const column: any = {
          field: item.field,
          title: item.title,
          minWidth: item.minWidth || "",
          width: item.width || "",
          sortable: item.isSort === "1",
          showOverflow: true,
        };
        if (item.field === "permissionType") {
          column.formatter = ({ row }) => {
            return row.permissionTypeText || "";
          };
        }
        if (item.field === "title") {
          column.treeNode = true;
        }
        return column;
      });

    // 操作列
    tableColumns.push({
      title: "操作",
      fixed: "right",
      // width: 260,
      slots: { default: "operate" },
    });

    // 更新 columns
    gridOptions.columns = [{ type: "checkbox", width: 60 }, ...tableColumns];
    gridOptions.toolbarConfig = setupToolbar(vuePermission.value);

    // 3. 请求数据
    let tableDataRes;
    if (last === "Equipment") {
      tableDataRes = await getQueryRowPage(first, params);
    } else {
      tableDataRes = await getQueryMapPage(last, params);
    }

    // 4. 更新数据和分页
    total.value = tableDataRes.count;
    gridOptions.data = tableDataRes.data; // 直接赋值给 gridOptions.data

    // 更新分页总数
    if (gridOptions.pagerConfig) {
      gridOptions.pagerConfig.total = tableDataRes.count;
    }
  } catch (err) {
    console.error("数据加载失败", err);
    gridOptions.data = [];
  } finally {
    loading.value = false;
  }
};
// ==================== 弹窗 ======================
// 打开弹窗并初始化表单
const openPopup = async (row?: RowVO) => {
  // 1. 获取需要加载字典的字段
  const needLoadFields = fieldList.value.filter(
    (field) =>
      field.isForm === "1" && field.formType === "select" && field.dictType
  );
  console.log(fieldList.value);
  const dictTypesToLoad = [...new Set(needLoadFields.map((f) => f.dictType))];

  // 2. 加载字典
  if (dictTypesToLoad.length > 0) {
    const promises = dictTypesToLoad.map((dictType) => getOptions(dictType));
    await Promise.all(promises);
  }

  popupFormItems.value = popupFormItems.value.map((item) => {
    const field = fieldList.value.find((f) => f.field === item.field);
    if (field && field.formType === "select" && field.dictType) {
      return {
        ...item,
        itemRender: {
          ...item.itemRender,
          options: dictCache.get(field.dictType) || [],
        },
      };
    }
    return item;
  });

  if (row) {
    // 4. 初始化表单值
    const res = await getRowById(lastSegment.value, { id: row.id });
    form.value = res;
  } else {
    form.value = {};
  }

  // 5. 打开弹窗
  showEditPopup.value = true;
};
// ==================== 弹窗事件 =====================

// ==================== 设置菜单弹窗 ==================
interface NodeVO {
  id: string;
  title: string;
  parentId?: string | null;
  permission: string | null | undefined;
  children?: NodeVO[];
  checked: boolean;
}
const roleId = ref<string>("");
const checkNodeKeys = ref<string[]>([]);
const treeOptions = reactive<VxeTreeProps<NodeVO>>({
  data: [],
  transform: false,
  childrenField: "children",
  keyField: "id",
  showCheckbox: true,
  expandAll: true,
});

const getMenuTreeData = async (id: string) => {
  try {
    const res = await getMenuTree({ roleId: id });
    const menuTreeData = res || [];

    const collectCheckedIds = (nodes: NodeVO[]): string[] => {
      const ids: string[] = [];
      const walk = (list: NodeVO[]) => {
        for (const node of list) {
          if (node.checked === true) {
            ids.push(node.id);
          }
          if (node.children?.length) {
            walk(node.children);
          }
        }
      };
      walk(nodes);
      return ids;
    };

    const checkedIds = collectCheckedIds(menuTreeData);
    treeOptions.data = menuTreeData;
    checkNodeKeys.value = checkedIds;
  } catch (err) {
    ElMessage.error("加载失败");
    treeOptions.data = [];
    checkNodeKeys.value = [];
  }
};

// 保存选中的菜单权限
const saveSelectedIds = async () => {
  if (!roleId.value) {
    ElMessage.warning("无效的角色ID");
    return;
  }

  const selectedIds = checkNodeKeys.value;

  const menuIdStr = ["ROOT", ...selectedIds].join(",");

  try {
    const result = await saveRoleMenu({
      roleId: roleId.value,
      menuIds: menuIdStr,
    });
    if (result.code == 0) {
      ElMessage.success("权限分配成功");
    } else {
      ElMessage.error(result.message);
    }
    settingMenuPopup.value = false;
  } catch (err) {
    ElMessage.error("保存失败，请重试");
  }
};

// ==================== 初始化 ====================

const initData = async () => {
  const pathSegments = route.path.split("/").filter(Boolean);
  const permissions = route.meta.permission || [];
  const allButtons = permToButtons(permissions);
  const { toolbarButtons, inTableButtons: ops } =
    splitButtonsByLocation(allButtons);

  vuePermission.value = toolbarButtons;
  inTableButtons.value = ops; // 存入响应式变量
  firstSegment.value = pathSegments[0] || "";
  lastSegment.value = pathSegments.pop() || "";

  const params = {
    pageNumber: 1,
    pageSize: pageSize.value,
  };

  await getDataTable(firstSegment.value, lastSegment.value, params);
};

onMounted(() => {
  initData();
});

watch(
  () => route.path,
  () => {
    initData();
  },
  { immediate: true }
);
</script>
<style lang="scss" scoped>
.table-main {
  margin-top: 16px;
  .alert-m {
    margin: 12px 0;
  }
}
</style>
